package biz

import (
	"context"
	pb "digitalhuman/api/storyboard/v1"
	"digitalhuman/models"
	"errors"
	"fmt"
	"github.com/go-kratos/kratos/v2/log"
)

type StoryRepo interface {
	UpdateState(context.Context, int, int) (bool, error)
	FindByID(context.Context, int) (*models.Storyboard, error)
	GetStoryWitExt(ctx context.Context, i int) (*pb.GetStoryboardReply, error)
	DeleteStoryById(i int, ownId int) error
	GetStoryListByUid(ctx context.Context, uid int, isDraft int) (*pb.ListStoryboardReply, error)
	GetStoriesWitExtByUid(ctx context.Context, uid int, isDraft int) (*pb.ListStoryboardReply, error)
	FindByUserName(context.Context, string) (*models.Storyboard, error)
	CreateStory(context.Context, *pb.CreateStoryboardRequestL, int) (*models.Storyboard, error)
	CreateStoryExtTable(ctx context.Context, uid int, storyboardId int, req *pb.CreateStoryboardRequestL) (*models.Storyboard, error)
	HandleSection(storyBoard *models.Storyboard) error
	CallBackProduce(ctx context.Context, req *pb.CallBackProduceRequest) error
	StartNatsSubCallBack() error
}

// StoryboardBiz UserBiz is a User usecase.
type StoryboardBiz struct {
	StoryboardData StoryRepo
}

// NewStoryboardBiz new a Storyboard usecase.
func NewStoryboardBiz(sd StoryRepo) *StoryboardBiz {
	fmt.Println("NewStoryboardBiz")
	err := sd.StartNatsSubCallBack()
	if err != nil {
		panic(err)
	}
	return &StoryboardBiz{
		StoryboardData: sd,
	}
}

func (s *StoryboardBiz) GetStory(ctx context.Context, storyId int) (*pb.GetStoryboardReply, error) {
	ret, err := s.StoryboardData.GetStoryWitExt(ctx, int(storyId))
	if err != nil {
		return nil, err
	}

	return ret, nil
}

func (s *StoryboardBiz) DeleteStory(storyId int, ownid int) error {
	err := s.StoryboardData.DeleteStoryById(storyId, ownid)
	if err != nil {
		return err
	}

	return nil
}

func (s *StoryboardBiz) ListStory(ctx context.Context, uid int, isDraft int) (*pb.ListStoryboardReply, error) {
	ret, err := s.StoryboardData.GetStoryListByUid(ctx, uid, isDraft)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (s *StoryboardBiz) ListStoryDraft(ctx context.Context, uid int) (*pb.ListStoryboardDraftReply, error) {
	ret, err := s.StoryboardData.GetStoriesWitExtByUid(ctx, uid, 1)
	if err != nil {
		return nil, err
	}
	re := &pb.ListStoryboardDraftReply{}
	for _, story := range ret.Storyboards {
		replyT := &pb.GetStoryboardDraftReply{}
		replyT.Id = story.Id
		replyT.Name = story.Name
		replyT.Description = story.Description
		if len(story.Sections) > 0 {
			if story.Sections[0].Human != nil {
				replyT.X = story.Sections[0].Human.X
				replyT.Y = story.Sections[0].Human.Y
				replyT.Width = story.Sections[0].Human.Width
				replyT.Height = story.Sections[0].Human.Height
				replyT.HumanId = story.Sections[0].Human.Asset.Id
			}
			if story.Sections[0].Background != nil {
				replyT.BackgroundId = story.Sections[0].Background.Asset.Id
			}

			if story.Sections[0].Text != nil {
				replyT.TextContent = story.Sections[0].Text.Content
				replyT.TextVcn = story.Sections[0].Text.Vcn
			}
		}
		re.Storyboards = append(re.Storyboards, replyT)
	}
	return re, nil
}

func (s *StoryboardBiz) ListStorySubmit(ctx context.Context, uid int) (*pb.ListStoryboardSubmitReply, error) {
	ret, err := s.StoryboardData.GetStoriesWitExtByUid(ctx, uid, 0)
	if err != nil {
		return nil, err
	}
	// pb.ListStoryboardReply 转换为 pb.ListStoryboardSubmitReply
	re := &pb.ListStoryboardSubmitReply{}
	for _, story := range ret.Storyboards {
		replyT := &pb.GetStoryboardSubmitReply{}
		replyT.Id = story.Id
		replyT.Name = story.Name
		if len(story.Sections) > 0 {
			replyT.VideoDuration = story.Sections[0].VideoDuration
			replyT.VideoCreatedAt = story.Sections[0].VideoCreatedAt
			replyT.VideoUrl = story.Sections[0].VideoUrl
			replyT.VideoExpiredAt = story.Sections[0].VideoExpiredAt
		}
		re.Storyboards = append(re.Storyboards, replyT)
	}

	return re, nil
}

func (uc *StoryboardBiz) CreateStory(ctx context.Context, req *pb.CreateStoryboardRequestL, uid int) (int, error) {
	var storyboardId int

	// 验证一下提交的参数
	for _, sectionReqTe := range req.Requests {
		if sectionReqTe.BackgroundId == 0 && sectionReqTe.HumanId == 0 && sectionReqTe.TextContent == "" {
			return 0, errors.New("参数不全")
		}
		if sectionReqTe.HumanId != 0 && (sectionReqTe.Width == 0 || sectionReqTe.Height == 0) {
			return 0, errors.New("human 参数不全")
		}
	}

	if storyboardId > 0 {
		storyboard, _ := uc.StoryboardData.FindByID(ctx, storyboardId)
		if storyboard.IsDraft == 0 && storyboard.ID > 0 {
			return 0, errors.New("不能修改已经提交的记录")
		}
	}

	if req.StoryboardId == 0 {
		// 创建storyboard section textAudio 数据表内容，并返回结果
		storyboardT, err := uc.StoryboardData.CreateStory(ctx, req, uid)
		if err != nil {
			return 0, err
		}
		storyboardId = storyboardT.ID
	} else {
		storyboardId = int(req.StoryboardId)
	}

	// 根据audioId查询audio 生成textAudio 异步协程生产
	go func(storyId int) {
		storyboardM, err := uc.StoryboardData.CreateStoryExtTable(ctx, uid, storyId, req)
		if err != nil {
			log.Error(err)
		}
		err = uc.StoryboardData.HandleSection(storyboardM) // 附属表创建成功之后 处理资源
		if err != nil {
			log.Error(err)
		}
	}(storyboardId)

	return storyboardId, nil
}

func (uc *StoryboardBiz) CallBackProduce(ctx context.Context, req *pb.CallBackProduceRequest) {
	err := uc.StoryboardData.CallBackProduce(ctx, req)
	if err != nil {
		log.Error(err)
	}
}

func (uc *StoryboardBiz) FindUserById(ctx context.Context, userId int) (*models.Storyboard, error) {
	return uc.StoryboardData.FindByID(ctx, userId)
}
